# Copyright (c) 2010, Ryan Bourgeois <bluedragonx@gmail.com>
# All rights reserved.
#
# This software is licensed under a modified BSD license as defined in the
# provided license file at the root of this project.  You may modify and/or
# distribute in accordance with those terms.
#
# This software is provided "as is" and any express or implied warranties,
# including, but not limited to, the implied warranties of merchantability and
# fitness for a particular purpose are disclaimed.

import sys, os.path, package
from argparse import ArgumentParser

default_files = {
    'use':      '/etc/portage/package.use',
    'keywords': '/etc/portage/package.keywords',
    'mask':     '/etc/portage/package.mask',
    'unmask':   '/etc/portage/package.unmask'}

def configure(args):
    ap = ArgumentParser(description='Manage contents Portage\'s package.* files.')
    ap.add_argument('-p', '--packages', nargs=1, dest='atoms', metavar='PKGS',
        help='Required.  A comma separated list of package atoms to work with.')
    ap.add_argument('-f', '--flags', dest='use', default=False, action='store_true',
        help='Modify package use flags.  Use flags may be passed via the ITEM arguments.  If -r/--remove is given then use flags may be omitted; the entire package line will be removed.  They are required in all other cases.')
    ap.add_argument('-k', '--keywords', dest='keywords', default=False, action='store_true',
        help='Modify package keywords.  Keywords may be passed via the ITEM arguments and are optional.')
    ap.add_argument('-m', '--mask', dest='mask', default=False, action='store_true',
        help='Mask packages.')
    ap.add_argument('-u', '--unmask', dest='unmask', default=False, action='store_true',
        help='Unmask packages.')
    ap.add_argument('-r', '--remove', dest='remove', default=False, action='store_true',
        help='Remove entries from the specified package.* file.  This must be used with -f/--flags, -k/--keywords, -m/--mask, or -u/--unmask.')
    ap.add_argument('-F', '--file', nargs=1, dest='file', metavar='FILE',
        help='An alternate file to modify.')
    ap.add_argument('items', nargs='*', metavar='ITEM',
        help='Use flag or keyword given as alternate input to -f/--flags or -k/--keywords.')
    config = ap.parse_args(args)

    if config.file is not None:
        config.file = config.file[0]

    actions = 0
    if config.use:
        actions = actions + 1
        if config.file is None:
            config.file = default_files['use']
        if config.items is None and not config.remove:
            ap.error('argument -f/--flags requires the one or more ITEM arguments be given when -r/--remove is not set')
    if config.keywords:
        actions = actions + 1
        if config.file is None:
            config.file = default_files['keywords']
    if config.mask:
        actions = actions + 1
        if config.file is None:
            config.file = default_files['mask']
    if config.unmask:
        actions = actions + 1
        if config.file is None:
            config.file = default_files['unmask']

    if config.atoms is None:
        ap.error('argument -p/--packages is required.')
    if actions == 0:
        ap.error('one of -f/--flags, -k/--keywords, -m/--mask, or -u/--unmask expected')
    if actions > 1:
        ap.error('only one of -f/--flags, -k/--keywords, -m/--mask, or -u/--unmask may be given')
    if config.file is not None and not os.path.exists(config.file):
        ap.error('argument -f/--file references a file that does not exist')
    config.atoms = config.atoms[0].split(',')
    return config

def main():
    config = configure(sys.argv[1:])
    if config.use:
        pkg = package.Use(config.file)
        use = None if len(config.items) == 0 else config.items
        if config.remove:
            for atom in config.atoms:
                pkg.remove(atom, use)
        else:
            for atom in config.atoms:
                pkg.update(atom, use)
        pkg.save()
    elif config.keywords:
        pkg = package.Keywords(config.file)
        keywords = None if len(config.items) == 0 else config.items
        if config.remove:
            for atom in config.atoms:
                pkg.remove(atom, keywords)
        else:
            for atom in config.atoms:
                pkg.add(atom, keywords)
        pkg.save()
    elif config.mask:
        pkg = package.Mask(config.file)
        if config.remove:
            for atom in config.atoms:
                pkg.remove(atom)
        else:
            for atom in config.atoms:
                pkg.add(atom)
        pkg.save()
    elif config.unmask:
        pkg = package.Unmask(config.file)
        if config.remove:
            for atom in config.atoms:
                pkg.remove(atom)
        else:
            for atom in config.atoms:
                pkg.add(atom)
        pkg.save()

if __name__ == '__main__':
    main()

